﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AdventureWorks.Entities;
using AdventureWorksData.DAO;
using AdventureWorks.Helpers;
using AdventureWorks.Exceptions;

namespace AdventureWorks.Business
{
	public class CustomerBusiness : IBusiness<Customer>, IDisposable
	{
		private readonly IUnitOfWork _db;
		private IEnumerable<Customer> _customers;

		public CustomerBusiness()
		{
			_db = new UnitOfWork();
		}

		public CustomerBusiness(IUnitOfWork entityDb)
		{
			_db = entityDb;
		}

		public IEnumerable<Customer> GetList(string sortOrder, string searchString)
		{
			_customers = _db.Customers.Get();
			FilterWithSearchString(searchString);
			SortOrder(sortOrder);

			return _customers;
		}

		private void FilterWithSearchString(string searchString)
		{
			if (!String.IsNullOrEmpty(searchString))
			{
				_customers = _customers.Where(c =>
					CustomComparer.CompareString(
						new String[] { c.ID.ToString(), c.FullName, c.EmailAddress, c.CompanyName, c.Phone, c.SalesPerson},
						searchString));
			}
		}

		private void SortOrder(String sortOrder)
		{
			switch (sortOrder)
			{
				case "Name Desc":
					_customers = _customers.OrderByDescending(o => o.FirstName);
					break;
				case "Company":
					_customers = _customers.OrderBy(o => o.CompanyName);
					break;
				case "Company Desc":
					_customers = _customers.OrderByDescending(o => o.CompanyName);
					break;
				case "Date":
					_customers = _customers.OrderBy(o => o.ModifiedDate);
					break;
				case "Date Desc":
					_customers = _customers.OrderByDescending(o => o.ModifiedDate);
					break;
				default:
					_customers = _customers.OrderBy(o => o.FirstName);
					break;
			}
		}

		public Customer Get(int id)
		{
			return _db.Customers.Get(id);
		}

		public void Insert(Customer entity)
		{
			if (entity.Validate())
			{
				_db.Customers.Insert(entity);
			}
			else
			{
				ThrowInvalidException();
			}
		}

		public void Update(Customer entity)
		{
			entity.ModifiedDate = DateTime.Now;
			if (entity.Validate())
			{
				_db.Customers.Update(entity);
			}
			else
			{
				ThrowInvalidException();
			}
		}

		public void Delete(int id)
		{
			_db.Customers.Delete(id);
		}

		public void Save()
		{
			_db.Save();
		}

		public void Dispose()
		{
			_db.Dispose();
		}


		public void ThrowInvalidException()
		{
			throw new BusinessException("Invalid Customer");
		}
	}
}
